﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;

using PetaPoco;
using Marking.Dashboard.Web.DataContracts;
using Marking.Dashboard.Web.ServiceContracts;

namespace Marking.Dashboard.Web.Services
{
    public class StockService : IStockService
    {
        public IEnumerable<StockDTO> LoadSalesStockInfos()
        {
            var db = this.CreateDb();
            db.EnableAutoSelect = false;

            var results = db
                .Query<WHStoreQueryResult>("EXEC [Pro_WHStoreQuery] @0, @1, @2, @3", null, null, null, null)
                .ToList();

            return this.CreateStockInfos(results);
        }

        public IEnumerable<StockDTO> LoadColouredClothStockInfos()
        {
            var db = this.CreateDb();
            db.EnableAutoSelect = false;

            var results = db
                .Query<PLStoreColorQueryResult>("EXEC [Pro_PLStoreColorQuery] @0, @1, @2", null, null, null)
                .ToList();

            return this.CreateStockInfos(results);
        }

        public IEnumerable<StockDTO> LoadClothStockInfos()
        {
            var db = this.CreateDb();
            db.EnableAutoSelect = false;

            var results = db
                .Query<PLStorePlanticleQueryResult>("EXEC [Pro_PLStorePlanticleQuery] @0, @1, @2, @3", null, null, null, null)
                .ToList();

            return this.CreateStockInfos(results);
        }

        private Database CreateDb()
        {
            return new Database("Marking");
        }

        private IEnumerable<StockDTO> CreateStockInfos(IEnumerable<IWHStoreQueryResult> results)
        {
            var stockQuantities =
                (from item in results.Where(x => x.StoreId != null)
                 group item by item.StoreId.Value into g
                 select new StockDTO
                 {
                     WarehouseId = g.First().StoreId.Value,
                     Warehouse = g.First().StoreName,
                     Quantity = g.Sum(x => x.StoreCount)
                 }).ToList();

            return stockQuantities;
        }

        private interface IWHStoreQueryResult
        {
            Guid? StoreId { get; }
            string StoreName { get; }
            long StoreCount { get; }
        }

        /// <summary>
        /// 大货库存。
        /// </summary>
        private class WHStoreQueryResult : IWHStoreQueryResult
        {
            public Guid? StoreId { get; set; }
            public string StoreName { get; set; }
            public long StoreCount { get; set; }
        }

        /// <summary>
        /// 色布库存。
        /// </summary>
        private class PLStoreColorQueryResult : IWHStoreQueryResult
        {
            public Guid? DyeworksId { get; set; }
            public string DyeworksName { get; set; }
            public long StoreCount { get; set; }

            public Guid? StoreId
            {
                get { return this.DyeworksId; }
            }

            public string StoreName
            {
                get { return this.DyeworksName; }
            }
        }

        /// <summary>
        /// 胚布库存。
        /// </summary>
        private class PLStorePlanticleQueryResult : IWHStoreQueryResult
        {
            public Guid? WeavingFactoryId { get; set; }
            public string WeavingFactoryName { get; set; }
            public Guid? DyeworksId { get; set; }
            public string DyeworksName { get; set; }
            public long StoreCount { get; set; }

            public Guid? StoreId
            {
                get { return this.DyeworksId ?? this.WeavingFactoryId; }
            }

            public string StoreName
            {
                get { return this.DyeworksName ?? this.WeavingFactoryName; }
            }
        }
    }
}